#include <string.h>

#include "libpbd_data.h"
#include "pbd_pblock.h"
#include "pbd_linux.h"
#include "pbd_type.h"
#include "pbd_error.h"

#define PBD_ETH_HDR_LEN 14
#define PBD_ETH_ADDR_LEN 6

struct pbd_ether_hdr{
	uint8 srcmac[PBD_ETH_ADDR_LEN];
	uint8 dstmac[PBD_ETH_ADDR_LEN];
	uint16 type;
};

int pbd_build_ether(pbd_handle_t *handle, uint8 *src, uint8 *dst, uint16 type)
{
	pbd_pblock_t *pblock;
	struct pbd_ether_hdr eth_hdr;

	if(!handle){
		pbd_print(PBD_LOG_WARNING, PBD_FUN, "Can't Use Empty Handle\n");
		return -1;
	}

	memset((char *)&eth_hdr, 0, sizeof(struct pbd_ether_hdr));
	memcpy(eth_hdr.srcmac, src, PBD_ETH_ADDR_LEN);
	memcpy(eth_hdr.dstmac, dst, PBD_ETH_ADDR_LEN);
	eth_hdr.type = htons(type);

	// create new packet block
	pblock = pbd_pblock_new(PBD_ETH_HDR_LEN, PBD_LAYER_2, PBD_PBLOCK_ETH, (char *)&eth_hdr, PBD_ETH_HDR_LEN);
	if(!pblock){
		pbd_print(PBD_LOG_WARNING, PBD_FUN, "New Pblock Fail\n");
		goto out_free;
	}

	// link new packet block
	if(pbd_pblock_add(&handle->pblock_head, pblock) < 0){
		pbd_print(PBD_LOG_WARNING, PBD_FUN, "Add New Pblock Fail\n");
		goto out_free;
	}
	return 1;

out_free:
	pbd_pblock_free(pblock);
	return -1;
}

int pbd_auto_build_ether(pbd_handle_t *handle, uint8 *dst, uint16 type)
{
	uint8 *src;

	// get src mac
	if (!handle->dev) {
		handle->dev = pbd_get_device();
		if(!handle->dev || !handle->dev[0]) {
			pbd_print(PBD_LOG_ERR, PBD_FUN, "No Devices To Fetch\n");
			return -1;
		}
	}
	
	src = pbd_get_hwaddr(handle->dev);
	if (!src)
		return -1;

	return pbd_build_ether(handle, src, dst, type);
}
